package com.weir.quarkus.base.system.resource;

import com.weir.quarkus.base.aspect.AutoLog;
import com.weir.quarkus.base.system.entity.SysModule;
import com.weir.quarkus.base.system.entity.SysUser;
import com.weir.quarkus.base.system.entity.SysUserRole;
import com.weir.quarkus.base.system.utils.AesEncyptUtil;
import com.weir.quarkus.base.system.utils.IpUtil;
import com.weir.quarkus.base.system.utils.VuePageUtil;
import com.weir.quarkus.base.system.vo.ResultDataVo;
import com.weir.quarkus.base.system.vo.UserVo;
import com.weir.quarkus.base.system.vo.VuePageListVo;
import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
import io.quarkus.hibernate.orm.panache.PanacheQuery;
import io.quarkus.panache.common.Sort;
//import io.quarkus.qute.Location;
//import io.quarkus.qute.Template;
//import io.quarkus.qute.TemplateInstance;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.json.JsonObject;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
import org.hibernate.query.criteria.internal.expression.ExpressionImpl;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 
 * @ClassName: SysUserResource
 * @Description: 后台用户API管理
 * @author weir
 * @date 2021年8月25日
 *
 */
@Tag(name = "用户管理")
@Path("/sys/user")
@ApplicationScoped
public class SysUserResource {

	@Context
	HttpServerRequest request;
	@Inject
	EntityManager em;

//	@Location("admin/userRole.html")
//	Template userRole;

	@Path("del")
	@DELETE
	@Transactional
	public Response deleteVue(UserVo userVo) {
		List<Integer> list = Arrays.asList(userVo.userIds.split(",")).stream().map(Integer::parseInt)
				.collect(Collectors.toList());
		SysUser.delete("id IN (?1)", list);
		return Response.ok().entity(new ResultDataVo<>(200, "删除成功", null)).build();
	}

	@AutoLog
	@GET
	@Path("user/list")
	public Response listVue(@QueryParam("page") Integer page, @QueryParam("pageSize") Integer pageSize,
			@QueryParam("userName") String userName, @QueryParam("email") String email) {
		StringBuilder jpql = new StringBuilder();
		List<Object> params = new ArrayList<>();
		if (StringUtils.isNotBlank(userName)) {
			if (!params.isEmpty()) {
				jpql.append(" and ");
			}
			jpql.append("userName like ?").append(params.size() + 1);
			params.add("%" + userName.trim() + "%");
		}
		if (StringUtils.isNotBlank(email)) {
			if (!params.isEmpty()) {
				jpql.append(" and ");
			}
			jpql.append("email like ?").append(params.size() + 1);
			params.add("%" + email.trim() + "%");
		}
		PanacheQuery<PanacheEntityBase> panacheQuery = null;
		if (params.isEmpty()) {
			panacheQuery = SysUser.findAll(Sort.descending("createTime")).page(page - 1, pageSize);

		} else {
			panacheQuery = SysUser.find(jpql.toString(), Sort.descending("createTime"), params).page(page - 1,
					pageSize);
		}
		VuePageListVo<SysUser> list = VuePageUtil.toPage(panacheQuery, new VuePageListVo<SysUser>(), page, pageSize);
		getRoleIds(list.list);
		
		
//		CriteriaBuilder cb = em.getCriteriaBuilder();
//		CriteriaQuery<SysUser> query = cb.createQuery(SysUser.class);
//		Root<SysUser> root = query.from(SysUser.class);
//		query.select(root);
//		List<Predicate> predicates = new ArrayList<>();
//		if (StringUtils.isNotBlank(userName)) {
//			Predicate u1 = cb.like(root.get("userName"),
//					"%" + userName.trim() + "%");
//			predicates.add(u1);
//		}
//		if (StringUtils.isNotBlank(email)) {
//			Predicate e1 = cb.like(root.get("email"),
//					"%" + email.trim() + "%");
//			predicates.add(e1);
//		}
//		for (Predicate predicate : predicates) {
//			query.where(predicate);
//		}
//		List<SysUser> resultList = em.createQuery(query)
//				.setFirstResult(page - 1)
//				.setMaxResults(pageSize)
//				.getResultList();
//		return Response.ok().entity(new ResultDataVo<>(200, "ok", resultList)).build();
		return Response.ok().entity(new ResultDataVo<>(200, "ok", list)).build();
	}
	
	private void getRoleIds(List<SysUser> list) {
		Map<Integer, SysUser> userMap = list.stream().collect(Collectors.toMap(SysUser::getId, a -> a, (k1, k2) -> k1));
		List<Integer> userIds = list.stream().map(SysUser::getId).collect(Collectors.toList());
		
		EntityManager entityManager = SysModule.getEntityManager();
		List resultList = entityManager.createNativeQuery("select user_id,GROUP_CONCAT(distinct(role_id)) roleIds "
				+ "from sys_user_role where user_id in (:ids) GROUP BY user_id").setParameter("ids", userIds).getResultList();
		for (Object row : resultList) {
			Object[] cells = (Object[]) row;
			
			SysUser sysUser = userMap.get(Integer.valueOf(cells[0].toString()));
			if (sysUser != null) {
				sysUser.roleList = Arrays.asList(cells[1].toString().split(",")).stream().map(Integer::parseInt).collect(Collectors.toList());
			}
		}
	}

//	@GET
//	@Path("roleUI/{id}")
//	@Produces(MediaType.TEXT_HTML)
//	public TemplateInstance userRole(@PathParam("id") Integer id) {
//		List<SysUserRole> list = SysUserRole.find("user_id", id).list();
//		List<Integer> roleIds = list.stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
//		UserVo users = new UserVo();
//		users.id = id;
//		users.roleIds = StringUtils.join(roleIds, ",");
//		return userRole.data("user", users);
//	}

	@POST
	@Path("role")
	@Transactional
	public Response addRole(UserVo userVo) {
		SysUser user = SysUser.findById(userVo.id);
		SysUserRole.delete("user_id", user.id);
		if (StringUtils.isNotBlank(userVo.roleIds)) {
			String[] rIds = StringUtils.split(userVo.roleIds, ",");
			for (String rId : rIds) {
				new SysUserRole(user.id, Integer.valueOf(rId)).persist();
			}
		}
		return Response.status(Status.OK).entity(new JsonObject().put("msg", "授权成功")).build();
	}

	@GET
	@Path("list")
	public Response list(@QueryParam("page") Integer page, @QueryParam("rows") Integer rows) {
		PanacheQuery<PanacheEntityBase> panacheQuery = SysUser.findAll().page(page - 1, rows);
		return Response.status(Status.OK)
				.entity(new JsonObject().put("total", panacheQuery.count()).put("rows", panacheQuery.list())).build();
	}

//	@Location("admin/userAdd.html")
//	Template userAdd;

//	@GET
//	@Path("addUI")
//	@Produces(MediaType.TEXT_HTML)
//	public TemplateInstance userAdd() {
//		return userAdd.data("user", null);
//	}

	@Path("user")
	@POST
	@Transactional
	public Response addVue(SysUser user) {
		if (user.id == null || user.id <= 0) {
			user.userPwd = AesEncyptUtil.encrypt(user.userPwd == null ? "123456" : user.userPwd);
			user.persist();
			addRole(user.id, user.roleList);
		} else {
			SysUser u = SysUser.findById(user.id);
			u.userName = user.userName;
			u.userPwd = user.userPwd;
			u.email = user.email;
			addRole(user.id, user.roleList);
		}
		return Response.ok().entity(new ResultDataVo<>(200, "ok", null)).build();
	}
	
	private void addRole(Integer id, List<Integer> roleList) {
		SysUserRole.delete("user_id", id);
		if (roleList != null) {			
			for (Integer roleId : roleList) {
				new SysUserRole(id, roleId).persist();
			}
		}
	}

	@POST
	@Transactional
	public Response add(SysUser user) {
		if (user.id == null || user.id <= 0) {
			user.userPwd = AesEncyptUtil.encrypt(user.userPwd == null ? "123456" : user.userPwd);
			user.persist();
		} else {
			SysUser u = SysUser.findById(user.id);
			u.userName = user.userName;
			u.userPwd = user.userPwd;
			u.email = user.email;
		}
		return Response.status(Status.OK).entity(new JsonObject().put("msg", "添加或修改成功")).build();
	}

//	@GET
//	@Path("editUI/{id}")
//	@Produces(MediaType.TEXT_HTML)
//	public TemplateInstance userEdit(@PathParam("id") Integer id) {
//		SysUser user = SysUser.findById(id);
//		return userAdd.data("user", user);
//	}

	@DELETE
	@Transactional
	public Response delete(UserVo userVo) {
		List<Integer> list = Arrays.asList(userVo.userIds.split(",")).stream().map(Integer::parseInt)
				.collect(Collectors.toList());
		SysUser.delete("id IN (?1)", list);
		return Response.status(Status.OK).entity(new JsonObject().put("msg", "删除成功")).build();
	}

	@GET
	@Path("ip")
	public String getIP() {
		return IpUtil.getSingleIp(request);
	}

	@GET
	@Path("ips")
	public Map<String, String> getIPs() {
		return IpUtil.getAllIpInfo(request);
	}

	@GET
	@Path("{id}")
	public SysUser get(@PathParam("id") Integer id) {
		SysUser u = SysUser.findById(id);
		String ujson = new JsonObject().put("user", u).toString();
		System.out.println("---------------u--------" + ujson);
		String user = new JsonObject(ujson).getValue("user").toString();

		System.out.println("---------------user--------" + user);
		SysUser u2 = new JsonObject(user).mapTo(SysUser.class);

		System.out.println("---------------u2--------" + u2);
		return u;
	}
}
